package ru.mirent;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.*;
import java.text.SimpleDateFormat;
import java.time.ZonedDateTime;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

public class OtherUtils {

    /**
     * TODO Перенести метод в отдельный класс и проверить работоспособность
     * @return
     */
    public static String getLicalhostIpAddress() {
        try {
            InetAddress inetAddress = InetAddress.getLocalHost();
            return inetAddress.getHostAddress();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return null;
    }

    /**
     * TODO Перенести метод в отдельный класс и отрефакторить
     */
    public static void showLocalHost() {
        try {
            Enumeration e = NetworkInterface.getNetworkInterfaces();

            while (e.hasMoreElements()) {
                NetworkInterface networkInterface = (NetworkInterface) e.nextElement();
                Enumeration ee = networkInterface.getInetAddresses();
                while (ee.hasMoreElements()) {
                    InetAddress inetAddress = (InetAddress) ee.nextElement();
                    System.out.println(inetAddress.getHostAddress());
                }
            }
        } catch (SocketException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * TODO Перенести метод в отдельный класс и отрефакторить
     */
    public static String getLicalhostIpAddress(String hostname) {
        try {
            Socket socket = new Socket();
            socket.connect(new InetSocketAddress(hostname, 80));
            return socket.getLocalAddress().getHostAddress();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        return null;
    }

    /**
     * Получить переменные окружения ОС.
     * TODO Перенести метод в отдельный класс и отрефакторить
     * @return список переменных окружения
     */
    public static Map<String, String> getEnvironmentProperties() {
        return System.getenv();
    }

    /**
     * Получить системные переменные JVM.
     * TODO Перенести метод в отдельный класс и отрефакторить
     * @return список системных переменных
     */
    public static Map<String, String> getSystemProperties() {
        Map<String, String> map = new HashMap<>();
        for (Map.Entry<Object, Object> entry: System.getProperties().entrySet()) {
            map.put(entry.getKey().toString(), entry.getValue().toString());
        }
        return map;
    }

    /**
     * TODO Перенести метод в отдельный класс и отрефакторить
     */
    public static void showEnvAndSysProperties() {
        System.out.println("System.getenv()");
        for (Map.Entry<String, String> entry: getEnvironmentProperties().entrySet()) {
            System.out.printf("%s - %s", entry.getKey(), entry.getValue());
        }

        System.out.println("System.getProperties()");
        for (Map.Entry<String, String> entry: getSystemProperties().entrySet()) {
            System.out.printf("%s - %s", entry.getKey(), entry.getValue());
        }
    }

    public static void runCommand(String command) {
        Runtime runtime = Runtime.getRuntime();
        Process process = null;

        try {
            process = runtime.exec(command);
            BufferedReader bufferedInputReader = new BufferedReader(
                    new InputStreamReader(process.getInputStream())
            );

            BufferedReader bufferedErrorReader = new BufferedReader(
                    new InputStreamReader(process.getErrorStream())
            );

            // Вернуть в методе
            // bufferedInputReader

            // Проверить на ошибку и если есть - выдавать исключение
            // bufferedErrorReader
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }


    /**
     * TODO Сделать примеров работы со временем и вынести в отдельный класс
     */
    public static String timeWork() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("");
        long currentTimeInMillis = ZonedDateTime.now().toInstant().toEpochMilli();

        return simpleDateFormat.format(currentTimeInMillis);
    }
}
